package com.lecyon.farm.service.impl;

import com.google.common.collect.Maps;
import com.lecyon.farm.comment.JwtUtil;
import com.lecyon.farm.common.constant.AuthorityConstant;
import com.lecyon.farm.common.constant.CommonConstant;
import com.lecyon.farm.common.constant.FarmSysConstant;
import com.lecyon.farm.common.exception.FarmException;
import com.lecyon.farm.entity.JsSysArea;
import com.lecyon.farm.entity.JsSysOffice;
import com.lecyon.farm.entity.JsSysUser;
import com.lecyon.farm.service.IFmWorkService;
import com.lecyon.farm.service.IJsSysAreaService;
import com.lecyon.farm.service.IJsSysOfficeService;
import com.lecyon.farm.service.IJsSysUserService;
import com.lecyon.farm.util.RedisUtils;
import com.lecyon.farm.util.ValidateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 查询缓存处理
 *
 * @author Yao Zheng
 * @Date 2019/11/22 11:22
 */
@Service
@Slf4j
public class CacheService {

    private RedisUtils redisUtils;

    private IJsSysUserService sysUserService;

    private AuthenticationService authenticationService;

    private IJsSysAreaService jsSysAreaService;

    private IJsSysOfficeService jsSysOfficeService;

    private IFmWorkService fmWorkService;

    /**
     * 系统初始化时加载
     */
    @PostConstruct
    public void initLoading() {
        boolean redisFlag;
        //缓存"系统默认用户"信息
//        redisFlag = initSystemInfo();
//        if (!redisFlag) {
//            log.error("loading default system information failed.");
//        }
    }

    /**
     * 加载系统级信息
     *
     * @return
     */
    public boolean initSystemInfo() {
        boolean redisFlag = false;
        List<JsSysArea> areaList = jsSysAreaService.list();
        Map<String, Object> jsSysAreaMap = null;
        if (CollectionUtils.isNotEmpty(areaList)) {
            jsSysAreaMap = areaList.stream().collect(Collectors.toMap(JsSysArea::getAreaCode, item -> item, (k1, k2) -> k1));
        }
        if (MapUtils.isNotEmpty(jsSysAreaMap)) {
            redisFlag = redisUtils.hmSet(FarmSysConstant.REDIS_KEY_SYS_AREA_TABLE, jsSysAreaMap);
        }
        List<JsSysOffice> jsSysOfficeList = jsSysOfficeService.list();
        Map<String, Object> jsSysOfficeMap = null;
        if (CollectionUtils.isNotEmpty(jsSysOfficeList)) {
            jsSysOfficeMap = jsSysOfficeList.stream().collect(Collectors.toMap(JsSysOffice::getOfficeCode, item -> item, (k1, k2) -> k1));
        }
        if (MapUtils.isNotEmpty(jsSysOfficeMap)) {
            redisFlag = redisUtils.hmSet(FarmSysConstant.REDIS_KEY_SYS_OFFICE_TABLE, jsSysOfficeMap);
        }
        return redisFlag;
    }

    /**
     * 加载系统用户的信息
     *
     * @return
     */
    public boolean initSystemUserAndTokenInformation() {
        boolean redisFlag;
        String userToken = AuthorityConstant.DEFAULT_SYS_TOKEN;
        String sysUserId = JwtUtil.getSysUserId(userToken);
        JsSysUser sysUserBean = sysUserService.getById(sysUserId);
        String account = sysUserBean.getLoginCode();
        //获取系统用户id，用于redis的key
        String key = String.valueOf(sysUserId);
        Map<String, Object> redisHash = Maps.newHashMap();
        redisHash.put("account", account);
        redisHash.put("userToken", userToken);
        List<String> roles = authenticationService.getUserRoleNameListByUserName(account);
        if (ValidateUtils.isNotNullOrEmpty(sysUserBean)) {
            redisHash.put(CommonConstant.CONTEXT_KEY_USERNAME, sysUserBean.getUserName());
            redisHash.put(CommonConstant.CONTEXT_KEY_USER_ID, sysUserBean.getUserCode());
            redisHash.put(CommonConstant.CONTEXT_KEY_USER_ROLES, roles);
        }
        //将token令牌存放到redis中
        redisFlag = redisUtils.hmSet(key, redisHash);
        if (!redisFlag) {
            throw new FarmException(CommonConstant.EX_DB_REDIS_ERROR, "Redis 操作异常,请联系系统管理员");
        }
        return true;
    }

    /**
     * ----------------------------- 分割线 以下是setter方法，用于替换field上的@Autowired -----------------------------
     **/

    @Autowired
    @Lazy
    public void setRedisUtils(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }

    @Autowired
    @Lazy
    public void setSysUserService(IJsSysUserService sysUserService) {
        this.sysUserService = sysUserService;
    }

    @Autowired
    @Lazy
    public void setJsSysAreaService(IJsSysAreaService jsSysAreaService) {
        this.jsSysAreaService = jsSysAreaService;
    }

    @Autowired
    @Lazy
    public void setFmWorkService(IFmWorkService fmWorkService) {
        this.fmWorkService = fmWorkService;
    }

    @Autowired
    @Lazy
    public void setAuthenticationService(AuthenticationService authenticationService) {
        this.authenticationService = authenticationService;
    }

    @Autowired
    @Lazy
    public void setJsSysOfficeService(IJsSysOfficeService jsSysOfficeService) {
        this.jsSysOfficeService = jsSysOfficeService;
    }

}
